﻿using System;
using Prompts.Service.PromptService.Implementation;
using Prompts.Service.Properties;
using Prompts.Service.ReportExecution;

namespace Prompts.Service.PromptService.Construction
{
    public class PromptServiceInjector
    {
        private static readonly IReportExecutionService ReportExecutionService = InjectReportExecutionService();

        public static PromptService Inject()
        {
            return new PromptService(InjectBaseReportParameterService(), InjectBaseReportInterpreter());
        }

        private static IBaseReportInterpreter<PromptInfo> InjectBaseReportInterpreter()
        {
            return new BaseReportInterpreter<PromptInfo>(
                InjectGlobalPromptProvider()
                , InjectEmptyPromptInfoProvider());
        }

        private static IEmbeddedPromptProvider<PromptInfo> InjectEmptyPromptInfoProvider()
        {
            return new EmbeddedPromptInfoProvider(
                InjectStrictDefaultValueProvider(),
                InjectSingleLevelPromptLevelProvider(),
                InjectEmptyPromptDefaultValueProvider());
        }

        private static IEmptyPromptDefaultValueProvider InjectEmptyPromptDefaultValueProvider()
        {
            return new EmptyPromptDefaultValueProvider();
        }

        private static IGlobalPromptProvider<PromptInfo> InjectGlobalPromptProvider()
        {
            return new GlobalPromptInfoService(
                InjectPromptReportParameterService()
                , InjectGlobalPromptInfoProvider()
                , InjectGlobalPromptBaseReportInfoMapper());
        }

        private static IGlobalPromptBaseReportInfoMapper InjectGlobalPromptBaseReportInfoMapper()
        {
            return new GlobalPromptBaseReportInfoMapper();
        }

        private static IGlobalPromptInfoProvider InjectGlobalPromptInfoProvider()
        {
            return new GlobalPromptInfoProvider(
                InjectSingleLevelPromptInfoProvider()
                , InjectHierarchyPromptInfoProvider()
                , InjectCasscadingPromptInfoProvider());
        }

        private static ICasscadingPromptInfoProvider InjectCasscadingPromptInfoProvider()
        {
            return new CasscadingPromptInfoProvider(InjectCasscadingPromptTypeProvider()
                                                    , InjectEmptyPromptLevelProvider()
                                                    , InjectLooseDefaultValuesProvider()
                                                    , InjectCasscadingSearchValidator());
        }

        private static ICasscadingSearchValidator InjectCasscadingSearchValidator()
        {
            return new CasscadingSearchValidator();
        }

        private static ILooseDefaultValuesProvider InjectLooseDefaultValuesProvider()
        {
            return new LooseDefaultValuesProvider();
        }

        private static IEmptyPromptLevelProvider InjectEmptyPromptLevelProvider()
        {
            return new EmptyPromptLevelProvider();
        }

        private static IPromptTypeProvider InjectCasscadingPromptTypeProvider()
        {
            return new CasscadingSearchPromptTypeProvider();
        }

        private static IHierarchyPromptInfoProvider InjectHierarchyPromptInfoProvider()
        {
            return new HierarchyPromptInfoProvider(InjectHierarchyPromptTypeProvider()
                                                   , InjectHierarchyPromptLevelProvider()
                                                   , InjectStrictDefaultValueProvider()
                                                   , InjectHierarchyPromptReportValidator());
        }

        private static IHierarchyPromptReportValidator InjectHierarchyPromptReportValidator()
        {
            return new HierarchyPromptReportValidator();
        }

        private static IPromptLevelProvider InjectHierarchyPromptLevelProvider()
        {
            return new HierarchyPromptLevelProvider();
        }

        private static IPromptTypeProvider InjectHierarchyPromptTypeProvider()
        {
            return new HierarchyPromptTypeProvider();
        }

        private static ISingleLevelPromptInfoProvider InjectSingleLevelPromptInfoProvider()
        {
            return new SingleLevelPromptInfoProvider(InjectSingleLevelPromptTypeProvider()
                                                     , InjectSingleLevelPromptLevelProvider()
                                                     , InjectStrictDefaultValueProvider());
        }

        private static IStrictDefaultValuesProvider InjectStrictDefaultValueProvider()
        {
            return new StrictDefaultValuesProvider();
        }

        private static IPromptLevelProvider InjectSingleLevelPromptLevelProvider()
        {
            return new SingleLevelPromptLevelProvider();
        }

        private static IPromptTypeProvider InjectSingleLevelPromptTypeProvider()
        {
            return new SingleLevelPromptTypeProvider();
        }

        private static IPromptReportParameterService InjectPromptReportParameterService()
        {
            return new PromptReportParameterService(
                InjectReportServerFolder(), 
                ReportExecutionService,
                InjectPromptReportNameParser());
        }

        private static IPromptReportNameParser InjectPromptReportNameParser()
        {
            return new PromptReportNameParser();
        }

        private static IReportServerFolder InjectReportServerFolder()
        {
            var path = Settings.Default.Prompt_Report_Folder;
            return new ReportServerFolder(path);
        }

        private static IBaseReportParameterService InjectBaseReportParameterService()
        {
            return new BaseReportParameterService(ReportExecutionService);
        }

        private static IReportExecutionService InjectReportExecutionService()
        {
            var executionService =
                new ReportExecutionService
                    {
                        Credentials = System.Net.CredentialCache.DefaultCredentials
                    };
            return executionService;
        }
    }
}